/** @format */
import { CommonUserService, CommonBaseService } from '../../service/common'
import { getSellerSession, getUserOrderlist, getTask } from '../../utils'
import { formatVipCbUrl, getShopVip } from '../../utils/common/vip'
import { CODE_TYPES } from '../../errorCode'
import { resultsModel, TBAPIS } from '../../sdk'

export type IInfo = 'session' | 'vipInfo' | 'taobaoOrderList' | 'credits' | 'task'

async function initBaseInfo(context: IContext<IParams>, baseInfos: ICheckControllerInfos, needInfos: IInfo[]) {
  const handler = context?.cloud?.dataspace?.context?.handler
  const userService = new CommonUserService(context)

  if (!baseInfos.activityInfo && handler !== 'getActivityBaseInfoById') {
    const baseService = new CommonBaseService(context)
    // 活动基本情况
    const activityInfo = await baseService.getBaseInfo(context.data.activityId)
    if (!activityInfo && !baseInfos?.noCheckActivity) return CODE_TYPES.ERROR_NO_ACTIVITY
    baseInfos.activityInfo = activityInfo
  }

  // 默认注入活动和用户信息并校验
  if (!baseInfos.userInfo) {
    // const userInfo = await userService.getUserInfo()
    // if (!userInfo && !baseInfos.noCheckUser) return CODE_TYPES.ERROR_NO_USER
    // baseInfos.userInfo = userInfo
  }

  if (needInfos.includes('session') && !baseInfos.session) {
    const { session, userNick } = await getSellerSession(context)
    baseInfos.session = session
  }

  if (needInfos.includes('vipInfo') && !baseInfos.vipInfo && handler !== 'getVipInfo') {
    const vipInfo = await getShopVip(context, baseInfos.activityInfo, formatVipCbUrl(context))
    baseInfos.vipInfo = vipInfo
  }

  if (needInfos.includes('taobaoOrderList') && !baseInfos.taobaoOrderList) {
    const taobaoOrderList = await getUserOrderlist(
      context,
      baseInfos?.userInfo?.createTime || baseInfos?.activityInfo?.startTime || Date.now(),
      Date.now()
    )
    baseInfos.taobaoOrderList = taobaoOrderList
  }

  if (needInfos.includes('credits') && !baseInfos.credits) {
    const credits = await TBAPIS.queryCredits(context)
    baseInfos.credits = credits
  }

  if (needInfos.includes('task') && !baseInfos.credits) {
    const task = await getTask(context)
    if (!task._id) return CODE_TYPES.ERROR_UPDATE_RETRY
    baseInfos.task = task
  }

  return baseInfos
}

export default function registeInfos(needInfos: IInfo[]) {
  return function (target: any, name: string, descriptor: PropertyDescriptor) {
    const method = descriptor.value
    descriptor.value = async function (...args: any[]) {
      const [context, otherArgs = {}, services = [], preCheckData = {}] = args

      const baseInfo = await initBaseInfo(context, otherArgs, needInfos)

      if ((baseInfo as ICodeType).code) return resultsModel.error(baseInfo as ICodeType)

      return method.apply(target, [context, { ...baseInfo, registed: true }, services, preCheckData])
    }
  }
}
